﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DepartmentRepository.cs" company="">
//   Copyright (c) 2010/2011 All Right Reserved
// </copyright>
// <summary>
//   Contains DepartmentRepository class declaration.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using EntityFrameworkExtensions;

namespace iBuproModel.Repositories.Classes
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using iBuproModel.Repositories.Interfaces;

    /// <summary>
    /// Implements IDepartmentRepository interface using linq to entities.
    /// </summary>
    public class DepartmentRepository : GenericRepository<Department>, IDepartmentRepository
    {
        public IEnumerable<Department> GetDepartmentsForUser(User user)
        {
            if (user.Roles.Contains(context.Roles.Single(r => r.Name == "Admin")))
                return this.GetAll();

            return context.Departments.Where(d => d.DepartmentPrincipal.Contains(user)).ToList();
        }
        
        public void UpdatePrincipalList(Department department, IEnumerable<int> ids)
        {
            var principalRole = context.Roles.Single(r => r.Name == "Principal");

            foreach (var principal in department.DepartmentPrincipal.Where(p => !ids.Contains(p.Id)))
            {
                // Is department principal only for this department
                if (principal.DepartmentPrincipalDepartments.Where(d => d.Id != department.Id).Count() == 0)
                {
                    principal.Roles.Remove(principalRole);
                }
            }

            department.DepartmentPrincipal.Clear();

            foreach (var id in ids)
            {
                var user = context.Users.First(r => r.Id == id);
                department.DepartmentPrincipal.Add(user);

                if (!user.Roles.Contains(principalRole))
                {
                    user.Roles.Add(principalRole);
                    context.SaveChanges();
                }
            }
        }

        public void UpdateAdministratorList(Department department, IEnumerable<int> ids)
        {
            var departmentAdminRole = context.Roles.Single(r => r.Name == "DepartmentAdmin");

            foreach (var admin in department.DepartmentAdministrators)
            {
                admin.Roles.Remove(departmentAdminRole);
            }

            department.DepartmentAdministrators.Clear();

            if (ids != null)
            {
                foreach (var id in ids)
                {
                    var user = context.Users.First(r => r.Id == id);

                    if (user.DepartmentAdministratorDepartment == null)
                    {
                        department.DepartmentAdministrators.Add(user);   
                    } else
                    {
                        throw new Exception("User is already administrator of another department.");
                    }

                    if (!user.Roles.Contains(departmentAdminRole))
                    {
                        user.Roles.Add(departmentAdminRole);
                        context.SaveChanges();
                    }
                }
            }
        }

        /*Rewrites base method. New method selects only visible members. This is because of deleting*/
        new public IQueryable<Department> GetAll()
        {
            return context.CreateObjectSet<Department>().OfTypeOnly<Department>().Where(f => f.Visible == true);
        }

    }
}
